home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 5 / Amiga Plus Sonderheft 1996 #5.iso / programme / povray / pov-ray_v2.2 / source / amiga.c next >
Encoding:
C/C++ Source or Header  |  1994-09-18  |  26.2 KB  |  1,028 lines

  1. /****************************************************************************
  2. *                   amiga.c
  3. *
  4. *  This module handles all of the Amiga-specific code for the raytracer.
  5. *
  6. *  from Persistence of Vision Raytracer
  7. *  Copyright 1993 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other 
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If 
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. * Modifications by Dave Park.
  23. *
  24. *****************************************************************************/
  25.  
  26.  
  27. #include "frame.h"
  28. #include "povproto.h"
  29.  
  30. #include <proto/exec.h>
  31. #include <proto/intuition.h>
  32. #include <proto/graphics.h>
  33. #include <proto/dos.h>
  34. #include <proto/expansion.h>
  35. #include <exec/types.h>
  36. #include <intuition/intuition.h>
  37. #include <graphics/display.h>
  38. #include <graphics/gfxbase.h>
  39. #include <graphics/gfx.h>
  40. #include <libraries/expansionbase.h>
  41.  
  42. /* Added 1 Mar 94 by George Leonidas Coulouris */
  43.  
  44. int matherr (struct exception *x);
  45.  
  46. /* */
  47.  
  48. void geta4(void);
  49. void Requestor_Handler(void);
  50. void Amiga_open(void);
  51. void Amiga_close(void);
  52. void open_requestor(void);
  53. void close_requestor(void);
  54. void write_byte(int x, int y, unsigned char n);
  55.  
  56. void write_cookie(unsigned char *brand, int line);
  57. void make_hame_palette(struct ViewPort *vp);
  58. void SetRGB8 (short reg, unsigned char rr, unsigned char gg,
  59.               unsigned char bb, short base);
  60.  
  61. int open_ham(int input_width, int inpupt_height);
  62. void  write_ham_pixel(UWORD x, UWORD y, UBYTE r, UBYTE g, UBYTE b);
  63. int open_hame(void);
  64. void  write_hame_pixel(int x, int y, char Red, char Green, char Blue);
  65. int open_firecracker(void);
  66. void  write_firecracker_pixel(UWORD x, UWORD y, UBYTE r, UBYTE g, UBYTE b);
  67.  
  68. extern unsigned int Options;
  69. extern char DisplayFormat;
  70. extern FRAME Frame;
  71.  
  72. #define INT_REV 29L
  73. #define GR_REV 29L
  74.  
  75. #define MAXDEPTHAGA    8
  76. #define MAXDEPTHNONAGA    6
  77.  
  78. struct IntuitionBase *IntuitionBase;
  79. struct GfxBase *GfxBase;
  80. struct Library *ExpansionBase;
  81.  
  82. struct Screen *s = NULL;
  83. volatile struct Window *w;
  84. struct Task *Requestor_Task;
  85.  
  86. volatile int Requestor_Running;
  87. volatile extern int Stop_Flag;
  88.  
  89. int width, height, depth;
  90. int bytesperrow;
  91. int leftedge, rightedge;
  92. int topedge, bottomedge;
  93.  
  94. int IsAGA;
  95.  
  96. struct Rectangle Rect1 =
  97.    {
  98.    0, 0, 0, 0
  99.    };
  100.  
  101. struct TagItem Ham_Screen_Tags[] =
  102.    {
  103.  
  104. /* Modified 1 Mar 94 by George Leonidas Coulouris */
  105.  
  106.        { SA_DClip, (ULONG) &Rect1 },
  107.  
  108. /* */
  109.  
  110.        { TAG_END, 0 }
  111.    };
  112.  
  113. struct ExtNewScreen Ham_Screen =
  114.    {
  115.    0, 0,
  116.    0, 0,
  117.    6,
  118.    0, 1,
  119.    HAM,
  120.    SCREENQUIET | NS_EXTENDED,
  121.    NULL,
  122.    (UBYTE *) "POV-Ray",
  123.    NULL,
  124.    NULL,
  125.    Ham_Screen_Tags
  126.    };
  127.  
  128.  
  129. struct NewScreen Ham_E_Screen =
  130.    {
  131.    0, 0,
  132.    0, 0,
  133.    4,
  134.    0, 1,
  135.    INTERLACE | HIRES,
  136.    SCREENQUIET,
  137.    NULL,
  138.    (UBYTE *) "POV-Ray",
  139.    NULL,
  140.    NULL
  141.    };
  142.  
  143. int lacer; /* if non-zero, screen is an interlace screen. Set this... */
  144.            /* ...as soon as you open your HAM-E screen.               */
  145.  
  146. unsigned char *fp0,*fp1,*fp2,*fp3; /* These are pointers which have been... */
  147.                                    /* ...cached from the screens BitMap[]   */
  148.                                    /* ...array. This allows us to get at    */
  149.                                    /* ...them much faster. Set them as soon */
  150.                                    /* ...as you open your HAM-E screen.     */
  151.  
  152. unsigned char bitpat[] =    /* This table is used as a table of masks... */
  153.   {                         /* ...to isolate bits in the HAM-E pixels    */
  154.     128,64,32,16,8,4,2,1,
  155.   };
  156.  
  157. unsigned char ham_cookie[] =  /* ham mode cookie... preceeds any HAM...    */
  158.   {                           /* ...color registers, and triggers hardware */
  159.     0xA2,0xF5,0x84,0xDC,      /* ...into ham mode.                         */
  160.     0x6D,0xB0,0x7F,0x18
  161.   };
  162.  
  163. struct Window *Requestor_Window;
  164. volatile struct MsgPort *Requestor_Port;
  165.  
  166. struct IntuiText chip Body_Text =
  167.    {0, 1, JAM1, 5, 10, NULL, (UBYTE *) "Click to abort the picture", NULL};
  168.  
  169. struct IntuiText chip Abort_Text =
  170.    {0, 1, JAM1, 5, 3, NULL, (UBYTE *) "Abort", NULL};
  171.  
  172. UWORD chip ColorTbl[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666,
  173.                        0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd,
  174.                        0xeee, 0xfff };
  175.  
  176. LONG last_red, last_green, last_blue, last_x, last_y;
  177.  
  178. /* Firecracker routines */
  179. typedef struct BOARD {
  180.     ULONG    orgb;
  181.     ULONG    orgb2;        /* autoincrementing */
  182.     UWORD    pad;
  183.     UBYTE    control0;
  184.     UBYTE    control1;
  185.     UWORD    y, x;
  186. } BOARD;
  187.  
  188. BOARD        *board;
  189.  
  190. void amiga_init_POVRAY(void )
  191.    {
  192.    (void) onbreak(amiga_close_all);
  193.    }
  194.  
  195. int matherr (x)
  196.    struct exception *x;
  197.    {
  198.  
  199. /* Commented out 1 Mar 94 by George Leonidas Coulouris
  200.  
  201.    fprintf (stderr, "Math error type: %d from function %s values: %g %g\n",
  202.            x->type, x->name, x->arg1, x->arg2);
  203.  
  204.    switch(x->type) 
  205.      {
  206.      case DOMAIN:
  207.      case OVERFLOW:
  208.         x->retval = 1.0e17;
  209.         break;
  210.  
  211.      case SING:
  212.      case UNDERFLOW:
  213.         x->retval = 0.0;
  214.         break;
  215.  
  216.      case TLOSS:
  217.      case PLOSS:
  218.         return (0);
  219.  
  220.      default:
  221.         break;
  222.      }
  223.  
  224. */
  225.  
  226.    return(1);
  227.    }
  228.  
  229. void Requestor_Handler ()
  230.    {
  231.    Requestor_Port = CreatePort ("ray trace port", 0L);
  232.    Requestor_Window = BuildSysRequest
  233.              (NULL, &Body_Text, NULL, &Abort_Text, GADGETUP, 280L, 60L);
  234.    Wait ((1 << Requestor_Port -> mp_SigBit)
  235.           | (1 << Requestor_Window -> UserPort -> mp_SigBit));
  236.  
  237.    Requestor_Running = FALSE;
  238.    Stop_Flag = TRUE;
  239.    }
  240.  
  241. void Amiga_open()
  242.    {
  243.    IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library",INT_REV);
  244.    if (IntuitionBase == NULL)
  245.      exit(FALSE);
  246.  
  247.    GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", GR_REV);
  248.    if (GfxBase == NULL)
  249.      exit(FALSE);
  250.  
  251.    IsAGA = (GfxBase->ChipRevBits0) ? TRUE : FALSE;
  252.  
  253.    Requestor_Running = FALSE;
  254.    }
  255.  
  256. void Amiga_close()
  257.    {
  258.    if (Requestor_Running) {
  259.       Signal (Requestor_Task, 1 << Requestor_Port -> mp_SigBit);
  260.       Delay (2L);
  261.       }
  262.  
  263.    if (Requestor_Window)
  264.       FreeSysRequest (Requestor_Window);
  265.  
  266.    Requestor_Window = NULL;
  267.  
  268.    CloseLibrary ((struct Library *) GfxBase) ;
  269.  
  270. /* Modified 1 Mar 94 by George Leonidas Coulouris */
  271.  
  272.    CloseLibrary ( (struct Library *) IntuitionBase) ;
  273.  
  274. /* */
  275.  
  276.    }
  277.  
  278. void open_requestor()
  279.    {
  280.    Requestor_Window = NULL;
  281.    Stop_Flag = FALSE;
  282.    Requestor_Running = TRUE;
  283.    Requestor_Task = CreateTask ("Raytrace Requestor", 2L,
  284.                                 (APTR) Requestor_Handler, 20000L);
  285.    }
  286.  
  287. void display_finished ()
  288.    {
  289.    if (Requestor_Running) {
  290.      Signal (Requestor_Task, 1 << Requestor_Port -> mp_SigBit);
  291.      Delay (2L);
  292.      }
  293.  
  294.    if (Requestor_Window)
  295.       FreeSysRequest (Requestor_Window);
  296.  
  297.    Requestor_Window = NULL;
  298.    if (Options & PROMPTEXIT)
  299.       {
  300.       printf ("Finished.\nPress CR to quit.\n");
  301.       getchar();
  302.       }
  303.    }
  304.  
  305. int open_ham (input_width, input_height)
  306. int input_width;
  307. int input_height;
  308. {
  309.     int screen_width, screen_height;
  310.     int viewmodes;
  311.  
  312.  
  313. #ifdef DBG
  314.  printf ("open_ham -\n");
  315.  printf ("  input_width: %4d input_height: %4d\n", input_width, input_height);
  316. #endif
  317.     viewmodes = HAM;
  318.  
  319.     if (input_width < 1 || input_height < 1)
  320.     {
  321.         display_close ();
  322.         printf ("? Size must be no smaller than 1 x 1\n");
  323.         return TRUE;
  324.     }
  325.  
  326.     if (input_width > 736 || input_height > 482)
  327.     {
  328.         display_close ();
  329.         printf ("? Size must be no larger than 736 x 482\n");
  330.         return TRUE;
  331.     }
  332.  
  333.     screen_width = 320;
  334.     if (input_width > 368 && input_width <= 736)
  335.     {
  336.         screen_width = 640;
  337.         viewmodes |= HIRES;
  338.     }
  339.     else if (input_width > 736)    /* Add higher resolutions */
  340.     {
  341.         screen_width = 640;
  342.         viewmodes |= HIRES;
  343.     }
  344.  
  345.     width = (input_width>screen_width) ? input_width : screen_width;
  346.  
  347.     leftedge = 0;
  348.     rightedge = width;
  349.     if (input_width < screen_width)
  350.     {
  351.         leftedge  = (screen_width - input_width) / 2;
  352.         rightedge = leftedge + input_width;
  353.     }
  354.  
  355.     screen_height = 200;
  356.     if (input_height > 241 && input_height <= 482)
  357.     {
  358.         screen_height = 400;
  359.         viewmodes |= LACE;
  360.     }
  361.     else if (input_height > 482)    /* Add higher resolutions */
  362.     {
  363.         screen_height = 400;
  364.         viewmodes |= LACE;
  365.     }
  366.  
  367.     height = (input_height>screen_height) ? input_height : screen_height;
  368.  
  369.     topedge = 0;
  370.     bottomedge = height;
  371.     if (input_height < screen_height)
  372.     {
  373.         topedge    = (screen_height - input_height) / 2;
  374.         bottomedge = topedge + input_height;
  375.     }
  376. #ifdef DBG
  377.  printf ("  screen_width:%4d screen_height:%4d\n", screen_width, screen_height);
  378.  printf ("  width:       %4d height:       %4d\n", width, height);
  379.  printf ("  leftedge:    %4d rightedge:    %4d\n", leftedge, rightedge);
  380.  printf ("  topedge:     %4d bottomedge:   %4d\n", topedge, bottomedge);
  381. #endif
  382.     depth = (IsAGA) ? MAXDEPTHAGA : MAXDEPTHNONAGA;
  383.  
  384.     Rect1.MaxX = width-1;
  385.     Rect1.MaxY = height-1;
  386.     Ham_Screen.Width = width;
  387.     Ham_Screen.Height = height;
  388.     Ham_Screen.Depth = depth;
  389.     Ham_Screen.ViewModes |= viewmodes;
  390.  
  391. /* Modified 1 Mar 94 by George Leonidas Coulouris */
  392.  
  393.     if ((s = (struct Screen *) OpenScreen ( (struct NewScreen *) &Ham_Screen)) == NULL)
  394.  
  395. /* */
  396.  
  397.     {
  398.        display_close ();
  399.        printf ("? Can't open screen.\n");
  400.        return TRUE;
  401.     }
  402.  
  403.     /* What did we actually get? */
  404.     width = s->Width;
  405.     height = s->Height;
  406.     depth = s->BitMap.Depth;
  407.     bytesperrow = s->BitMap.BytesPerRow;
  408.  
  409. #ifdef DBG
  410.  printf ("  actual_width:%4d actual_height:%4d\n", width, height);
  411.  printf ("  actual_depth:%4d\n", depth);
  412.  printf ("  bytesperrow: %4d\n", bytesperrow);
  413. #endif
  414.     ShowTitle (s, FALSE);
  415.  
  416.     LoadRGB4 (&(s->ViewPort), ColorTbl, 16L);
  417.     SetAPen (&(s->RastPort), 0L);
  418.     RectFill (&(s -> RastPort), 0L, 0L, width-1, height-1);
  419.  
  420.     return FALSE;
  421. }
  422.  
  423. #define absdif(x,y) ((x > y) ? (x - y) : (y - x))
  424. #define max3(x,y,z) ((x>y)?((x>z)?1:3):((y>z)?2:3))
  425.  
  426. #define HAM6_MASK    0x000F
  427. #define HAM6_RED    0x20
  428. #define HAM6_GREEN    0x30
  429. #define HAM6_BLUE    0x10
  430.  
  431. #define HAM8_MASK    0x003F
  432. #define HAM8_RED    0x80        //  1000 0000
  433. #define HAM8_GREEN    0xC0        //  1100 0000
  434. #define HAM8_BLUE    0x40        //  0100 0000
  435.  
  436. void write_ham_pixel (x, y, Red, Green, Blue)
  437. UWORD x, y;
  438. UBYTE Red, Green, Blue;
  439. {
  440.    register unsigned long index;
  441.    register int i;
  442.    register char *addr;
  443.    register UBYTE colour, mask, colour_mask;
  444.    UBYTE delta_red, delta_green, delta_blue;
  445.  
  446.  
  447.    y += topedge;
  448.    x += leftedge;
  449.  
  450.    if (y < last_y)
  451.       return;
  452.  
  453.    if (last_y != y) {
  454.       last_y = y;
  455.       last_red = last_green = last_blue = 0;
  456.       }
  457.    else
  458.       if (x <= last_x)
  459.          return;
  460.  
  461.    last_x = x;
  462.  
  463.    if (IsAGA) {
  464.       Red   = (Red   >> 2) & HAM8_MASK;
  465.       Green = (Green >> 2) & HAM8_MASK;
  466.       Blue  = (Blue  >> 2) & HAM8_MASK;
  467.    }
  468.    else {
  469.       Red   = (Red   >> 4) & HAM6_MASK;
  470.       Green = (Green >> 4) & HAM6_MASK;
  471.       Blue  = (Blue  >> 4) & HAM6_MASK;
  472.    }
  473.  
  474.    delta_red   = absdif (Red, last_red);
  475.    delta_green = absdif (Green, last_green);
  476.    delta_blue  = absdif (Blue, last_blue);
  477.  
  478.    if (IsAGA) {
  479.       switch (max3(delta_red, delta_green, delta_blue)) {
  480.       case 1:
  481.          last_red = Red;
  482.          colour = HAM8_RED   | Red;
  483.          break;
  484.       case 2:
  485.          last_green = Green;
  486.          colour = HAM8_GREEN | Green;
  487.          break;
  488.       case 3:
  489.          last_blue = Blue;
  490.          colour = HAM8_BLUE  | Blue;
  491.          break;
  492.       }
  493.    }
  494.    else {
  495.       switch (max3(delta_red, delta_green, delta_blue)) {
  496.       case 1:
  497.          last_red = Red;
  498.          colour = HAM6_RED   | Red;
  499.          break;
  500.       case 2:
  501.          last_green = Green;
  502.          colour = HAM6_GREEN | Green;
  503.          break;
  504.       case 3:
  505.          last_blue = Blue;
  506.          colour = HAM6_BLUE  | Blue;
  507.          break;
  508.       }
  509.    }
  510.  
  511.    index = (bytesperrow * y) + (x >> 3);
  512.    mask = 0x80 >> (x & 7);
  513.  
  514.    colour_mask = 1;
  515.  
  516.    for (i = 0 ; i < ((IsAGA) ? MAXDEPTHAGA : MAXDEPTHNONAGA) ; i++) {
  517.       addr = &s->BitMap.Planes[i][index];
  518.       *addr &= ~mask;
  519.       *addr |= (colour&colour_mask) ? mask : 0x00;
  520.       colour_mask <<= 1;
  521.       }
  522.    }
  523.  
  524. int open_hame ()
  525. {
  526.     int screen_width, screen_height;
  527.  
  528.  
  529.     screen_width = GfxBase->NormalDisplayColumns>>1;
  530.     Ham_E_Screen.Width = screen_width<<1;
  531.     screen_height = GfxBase->NormalDisplayRows<<1;
  532.     Ham_E_Screen.Height = screen_height+2;
  533.  
  534.     if ((s = (struct Screen *) OpenScreen (&Ham_E_Screen)) == NULL)
  535.     {
  536.         display_close ();
  537.         return (TRUE);
  538.     }
  539.  
  540.     ShowTitle (s, FALSE);
  541.  
  542.     lacer = 1;
  543.  
  544.     fp0 = s->BitMap.Planes[0];
  545.     fp1 = s->BitMap.Planes[1];
  546.     fp2 = s->BitMap.Planes[2];
  547.     fp3 = s->BitMap.Planes[3];
  548.  
  549.     make_hame_palette(&s->ViewPort);
  550.  
  551.     SetAPen (&(s->RastPort), 0L);
  552.     RectFill (&(s -> RastPort), 0L, 0L, Ham_E_Screen.Width-1, 1);
  553.     SetAPen (&(s->RastPort), 1L);
  554.     RectFill (&(s -> RastPort), 0L, 2L, Ham_E_Screen.Width-1,
  555.                                         Ham_E_Screen.Height-1);
  556.     write_cookie(ham_cookie, 0);
  557.     SetRGB8 (0x11, 0x80, 0x80, 0x80, 0);
  558.  
  559.     return FALSE;
  560. }
  561.  
  562. void write_hame_pixel (x, y, Red, Green, Blue)
  563.    int x, y;
  564.    char Red, Green, Blue;
  565.    {
  566.    register unsigned char colour;
  567.    short delta_red, delta_green, delta_blue;
  568.  
  569.    if (y < last_y)
  570.       return;
  571.  
  572.    if ((x >= width) || (y >= height))
  573.       return;
  574.  
  575.    if (last_y != y) {
  576.       last_y = y;
  577.       last_red = last_green = last_blue = 0;
  578.       }
  579.    else
  580.       if (x <= last_x)
  581.          return;
  582.  
  583.    last_x = x;
  584.  
  585.    Red = (Red >> 2) & 0x3F;
  586.    Green = (Green >> 2) & 0x3F;
  587.    Blue = (Blue >> 2) & 0x3F;
  588.  
  589.    delta_red = absdif (Red, last_red);
  590.    delta_green = absdif (Green, last_green);
  591.    delta_blue = absdif (Blue, last_blue);
  592.  
  593.    switch (max3(delta_red, delta_green, delta_blue)) {
  594.       case 1:
  595.          last_red = Red;
  596.          colour = 0x80 + Red;
  597.          break;
  598.       case 2:
  599.          last_green = Green;
  600.          colour = 0xc0 + Green;
  601.          break;
  602.       case 3:
  603.          last_blue = Blue;
  604.          colour = 0x40 + Blue;
  605.          break;
  606.       }
  607.  
  608.    write_byte (x, y+2, colour);
  609.    }
  610.  
  611. int open_firecracker()
  612. {
  613.     struct ConfigDev    *dev;
  614.     ULONG            i;
  615.  
  616.     ExpansionBase = OpenLibrary("expansion.library", 0L);
  617.     if (!ExpansionBase) {
  618.         printf("No expansion library\n");
  619.         return TRUE;
  620.     }
  621.  
  622.     dev = FindConfigDev(NULL, 0x838, 0);
  623.     if (dev) {
  624.         board = (BOARD *)dev->cd_BoardAddr;
  625.     }
  626.     else {
  627.         printf("Can't find FireCracker\n");
  628.         return TRUE;
  629.     }
  630.  
  631.     CloseLibrary((struct Library *) ExpansionBase);
  632.         height = 482;
  633.  
  634.         if (Frame.Screen_Width > 768) {
  635.        board->control0 = 0xf8;
  636.            width = 1024;
  637.            }
  638.         else if (Frame.Screen_Width > 512) {
  639.        board->control0 = 0xb8;           
  640.            width = 768;
  641.            }
  642.         else if (Frame.Screen_Width > 384) {
  643.        board->control0 = 0x78;
  644.            width = 512;
  645.            }
  646.         else {
  647.        board->control0 = 0x38;
  648.            width = 384;
  649.            }
  650.  
  651.     board->control1 = 0x7f;
  652.     board->y = 0; board->x = 0;
  653.     for (i=0; i<width*482; i++) {
  654.            /* I write to the auto-increment and non-autoincrement registers
  655.               to make this work on 68000's as well as 68020's. */
  656.            board->orgb  = 0x40404040;
  657.            board->orgb2 = 0x40404040;
  658.            }
  659.  
  660.     return FALSE;
  661. }
  662.  
  663.  
  664. void write_firecracker_pixel(x,y, r,g,b)
  665. UWORD    x,y;
  666. UBYTE    r,g,b;
  667. {
  668.     ULONG        v1,v2,v3,v;
  669.         int             new_x, new_y;
  670.  
  671.     v1 = r; v2 = g; v3 = b;
  672.     v = ((v1<<16)&0xff0000) + ((v2<<8)&0xff00) + (v3&0xff);
  673.  
  674.     new_y = y+(482-Frame.Screen_Height)/2; new_x = x+(width-Frame.Screen_Width)/2;
  675.         if ((new_x >= 0) && (new_y >= 0)
  676.             && (new_x < width) && (new_y < 482)) {
  677.            board->y = new_y;
  678.            board->x = new_x;
  679.        board->orgb2 = v;
  680.            }
  681. }
  682.  
  683. /*:
  684. .n write_byte()
  685. .k low_level write_byte byte_write write_pixel
  686. .b
  687.  
  688. SYNOPSIS:   void write_byte(x,y,n);
  689.                 short x;
  690.                 int y;
  691.                 unsigned char n;
  692.  
  693. FUNCTION:   This function is similar to the Amiga's WritePixel routine.
  694.             is simply takes the incoming position and value and writes
  695.             them to the HAM-E screen appropriately.
  696.  
  697. INPUTS:     x - horizontal position on screen.
  698.             y - vertical position on screen.
  699.             n - value 0-255 to write in the pixel.
  700.  
  701. RESULTS:    None
  702.  
  703. BUGS:       None Known.
  704.  
  705. LIMITATIONS:Hard coded for screen width of 320 pixels (640 hi-res pixels)
  706.  
  707. SEE ALSO:   Global variables "fp3", "fp2", "fp1", "fp0", "bitpat[]"
  708.  
  709. :*/
  710.  
  711. void write_byte(x,y,n)
  712.   int x;
  713.   int y;
  714.   unsigned char n;
  715.   {
  716.   register int ypos,byte_offset;
  717.   register short bit_offset;
  718.     ypos = y * 80; /* index to correct scan line - note hard coded width! */
  719.     bit_offset = (x << 1) & 7; /* find base bit position */
  720.     byte_offset = (x >> 2);   /* find base byte offset */
  721.     if (n & 128) *(fp3 + ypos + byte_offset) |= bitpat[bit_offset];
  722.             else *(fp3 + ypos + byte_offset) &= ~bitpat[bit_offset];
  723.     if (n &  64) *(fp2 + ypos + byte_offset) |= bitpat[bit_offset];
  724.             else *(fp2 + ypos + byte_offset) &= ~bitpat[bit_offset];
  725.     if (n &  32) *(fp1 + ypos + byte_offset) |= bitpat[bit_offset];
  726.             else *(fp1 + ypos + byte_offset) &= ~bitpat[bit_offset];
  727.     if (n &  16) *(fp0 + ypos + byte_offset) |= bitpat[bit_offset];
  728.             else *(fp0 + ypos + byte_offset) &= ~bitpat[bit_offset];
  729.     bit_offset++; /* to next nybble */
  730.     if (bit_offset == 8) /* carry into next byte? */
  731.       {
  732.         bit_offset=0;
  733.         byte_offset++;
  734.       }
  735.     if (n & 8) *(fp3 + ypos + byte_offset) |= bitpat[bit_offset];
  736.           else *(fp3 + ypos + byte_offset) &= ~bitpat[bit_offset];
  737.     if (n & 4) *(fp2 + ypos + byte_offset) |= bitpat[bit_offset];
  738.           else *(fp2 + ypos + byte_offset) &= ~bitpat[bit_offset];
  739.     if (n & 2) *(fp1 + ypos + byte_offset) |= bitpat[bit_offset];
  740.           else *(fp1 + ypos + byte_offset) &= ~bitpat[bit_offset];
  741.     if (n & 1) *(fp0 + ypos + byte_offset) |= bitpat[bit_offset];
  742.           else *(fp0 + ypos + byte_offset) &= ~bitpat[bit_offset];
  743.   }
  744.  
  745. /*:
  746. .n write_cookie()
  747. .k cookie low_level setup configure
  748. .b
  749.  
  750. SYNOPSIS:   void write_cookie(brand,line);
  751.                 unsigned char *brand;
  752.                 int line;
  753.  
  754. FUNCTION:    This function writes the cookie on a particular line.
  755.              The variable "brand" is a pointer to an arrary of data
  756.              that contains the particular cookie for the mode you want.
  757.              These arrays are the global ones "ham_cookie[]" and
  758.              "reg_cookie[]".
  759.              
  760.              Call as:
  761.              
  762.                   write_cookie(ham_cookie,line);
  763.                               -or-
  764.                   write_cookie(reg_cookie,line);
  765.              
  766.              Note: If you have a four line palette, you need to call
  767.              this function for each successive line the palette exists
  768.              upon, for example:
  769.              
  770.                   write_cookie(reg_cookie,0);
  771.                   write_cookie(reg_cookie,1);
  772.                   write_cookie(reg_cookie,2);
  773.                   write_cookie(reg_cookie,3);
  774.                   
  775.                         -or-
  776.                   
  777.                   for (i=0; i<4; i++)
  778.                     {
  779.                       write_cookie(reg_cookie,i);
  780.                     }
  781.              
  782.              If the global variable "lacer" is set, this function will
  783.              write the cookie data on the appropriate lines in both
  784.              fields... sending four lines of cookie to the function
  785.              with the lines 0,1,2,3 will write cookies on line pairs
  786.              0-1, 2-3, 4-5, and 6-7.
  787.  
  788. INPUTS:     A pointer to the apropriate cookie and the line to put it on.
  789.  
  790. RESULTS:    None
  791.  
  792. BUGS:       None Known.
  793.  
  794. LIMITATIONS:None Known.
  795.  
  796. SEE ALSO:   The global variable "lacer" and the "ham_cookie[]"
  797.             and reg_cookie[] global arrays.
  798.  
  799. :*/
  800. void write_cookie(brand,line)
  801.   unsigned char *brand;
  802.   int line;
  803.   {
  804.   int i;
  805.     if (lacer) /* we need double the cookie data! */
  806.       {
  807.         for (i=0; i<8; i++)
  808.           {
  809.             write_byte(i,line*2,brand[i]);
  810.             write_byte(i,(line*2)+1,brand[i]);
  811.           }
  812.       }
  813.     else
  814.       {
  815.         for (i=0; i<8; i++)
  816.           {
  817.             write_byte(i,line,brand[i]);
  818.           }
  819.       }
  820.   }
  821.  
  822. /*:
  823. .n make_hame_palette()
  824. .k amiga_palette palette_amiga setup configure
  825. .b
  826.  
  827. SYNOPSIS:   void make_hame_palette(vp);
  828.                 struct ViewPort *vp;
  829.  
  830. FUNCTION:   Sets palette for Amiga side of hardware: The palette here is
  831.             designed to achieve two independant goals. First, and most
  832.             importantly, it creates a situation where the IRGB lines at
  833.             the Amiga's data port will exactly mirror the data in the
  834.             bitplanes of the screen as each pixel is emitted. 
  835.             Secondly, this palette makes the images visible, if not
  836.             sensible, on a non HAM-e equipped Amiga... Hopefully this
  837.             distinctive color palette will quickly cue the user that
  838.             they are missing something good. :^)
  839.             
  840.             IRGB to 12 bit correspondence:
  841.             
  842.             bit 8 - b3 of red
  843.             bit 4 - b3 of green
  844.             bit 2 - b3 of blue
  845.             bit 1 - b0 of blue
  846.  
  847. INPUTS:     A pointer to the ViewPort that "belongs" to this screen.
  848.  
  849. RESULTS:    None
  850.  
  851. BUGS:       None Known.
  852.  
  853. LIMITATIONS:None Known.
  854.  
  855. SEE ALSO:   
  856.  
  857. :*/
  858. void make_hame_palette(vp)
  859.   struct ViewPort *vp;
  860.   {
  861.   int rr,gg,bb,i;
  862.   int col;
  863.     col=0;
  864.     for (i=0; i<16; i++)
  865.       {
  866.         rr=0; gg=0; bb=0;
  867.         if (i & 8) rr  = 8; /* this builds the IRGB bit outputs...   */
  868.         if (i & 4) gg  = 8; /* ...these four bits are all that are   */
  869.         if (i & 2) bb  = 8; /* ...required to make the HAM-E run,    */
  870.         if (i & 1) bb |= 1; /* ...they xfer b0->b3 to the IRGB lines */
  871.         if (i != 0)     /* we don't mess with c0 - we leave it black */
  872.           {
  873.             rr += (col & 7); /* build strange colors in cregs 1-15...  */
  874.             col += 2;        /* ...these extra bits sent to the color  */
  875.             gg += (col & 7); /* ...registers make amiga palette very   */
  876.             col += 2;        /* ...interesting to look at if the HAM-E */
  877.             bb += (col & 6); /* ...is NOT attached. Otherwise useless. */
  878.             col += 2;        /* ...The code in this "if" is optional.  */
  879.           }
  880.         SetRGB4(vp,i,rr,gg,bb); /* this actually sets the Amiga color regs */
  881.       }
  882.   }
  883.  
  884. /*:
  885. .n SetRGB8()
  886. .k palette_hame hame_palette setup configure
  887. .b
  888.  
  889. SYNOPSIS:   void SetRGB8(reg,rr,gg,bb,base);
  890.                 int reg,rr,gg,bb,base;
  891.  
  892. FUNCTION:   This routine sets the color registers in the HAM-E hardware.
  893.             It can handle color registers located at any point on screen,
  894.             by setting the "base" variable to the starting scan line where
  895.             the color registers exist. Normally, the cookie and it's
  896.             associated color registers are located beginning at scan line 0.
  897.             If the screen is an interlace screen, this routine will set both
  898.             set of color registers identically; when in interlace, the
  899.             HAM-E maintains separate sets of color registers for the
  900.             odd and even interlace fields. Since this routine sets both
  901.             sets of color registers identically, you don't have to
  902.             worry about dealing with this feature.
  903.             
  904. INPUTS:     reg  - the color register number from 0 to 255 to be set
  905.             rr   - the red value from 0-255
  906.             gg   - the green value from 0-255
  907.             bb   - the blue value from 0-255
  908.             base - the starting scan line of the first coookie position
  909.                    (usually zero)
  910.  
  911. RESULTS:    None
  912.  
  913. BUGS:       None Known.
  914.  
  915. LIMITATIONS:None Known.
  916.  
  917. SEE ALSO:   The global variable "lacer"
  918.  
  919. :*/
  920. void SetRGB8(reg,rr,gg,bb,base)
  921.   short reg;
  922.   unsigned char rr,gg,bb;
  923.   short base;
  924.   {
  925.   short p_row,p_index;
  926.     p_row = (reg >> 6) + base;           /* palette row 0-3.  */
  927.     p_index = ((reg & 0x3f) * 3) + 8;    /* reg 0-63 in p_row */
  928.     if (lacer) /* then we need both fields! */
  929.       {
  930.         /* for the even field: */
  931.         write_byte(p_index,   p_row*2, rr);         /* put RED value     */
  932.         write_byte(p_index+1, p_row*2, gg);         /* put GREEN value   */
  933.         write_byte(p_index+2, p_row*2, bb);         /* put BLUE value    */
  934.         
  935.         /* here is the stuff for the ODD field: */
  936.         write_byte(p_index,   (p_row*2)+1, rr);     /* put RED value     */
  937.         write_byte(p_index+1, (p_row*2)+1, gg);     /* put GREEN value   */
  938.         write_byte(p_index+2, (p_row*2)+1, bb);     /* put BLUE value    */
  939.       }
  940.     else /* just write to one field */
  941.       {
  942.         write_byte(p_index,   p_row, rr);     /* put RED value     */
  943.         write_byte(p_index+1, p_row, gg);     /* put GREEN value   */
  944.         write_byte(p_index+2, p_row, bb);     /* put BLUE value    */
  945.       }
  946.   }
  947.  
  948. void display_init (input_width, input_height)
  949. int input_width, input_height;
  950. {
  951.     Amiga_open();
  952.     open_requestor();
  953.  
  954.     Delay (10);
  955.  
  956.     last_red = last_green = last_blue = 0;
  957.     last_x = last_y = -1;
  958.  
  959.     if (DisplayFormat == 'E') {
  960.         if (open_hame () == TRUE) {
  961.         display_close ();
  962.         exit (FALSE);
  963.         }
  964.     }
  965.     else if (DisplayFormat == 'F') {
  966.         if (open_firecracker () == TRUE) {
  967.         display_close ();
  968.         exit (999);
  969.         }
  970.     }
  971.     else {
  972.         if (DisplayFormat != '2')    /*  If not +d2, then force */
  973.         IsAGA = FALSE;        /*    AGA off              */
  974.  
  975.         if (IsAGA)
  976.         printf ("(Rendering in AGA)\n");
  977.  
  978.         if (open_ham (input_width, input_height) == TRUE) {
  979.         display_close ();
  980.         exit (FALSE);
  981.         }
  982.     }
  983. }
  984.  
  985. void display_close ()
  986.    {
  987.    if (Requestor_Running) {
  988.       Signal (Requestor_Task, 1 << Requestor_Port -> mp_SigBit);
  989.       Delay (2L);
  990.       }
  991.  
  992.    if (Requestor_Window)
  993.       FreeSysRequest (Requestor_Window);
  994.  
  995.    Requestor_Window = NULL;
  996.  
  997.    if (s != NULL) {
  998.       CloseScreen (s);
  999.       s = NULL;
  1000.       }
  1001.    }
  1002.  
  1003. void display_plot (x, y, Red, Green, Blue)
  1004.    int x, y;
  1005.  
  1006. /* Modified 1 Mar 94 by George Coulouris */
  1007.  
  1008.    unsigned char Red, Green, Blue;
  1009.  
  1010. /* */
  1011.  
  1012.    {
  1013.    if (DisplayFormat == 'E')
  1014.     return (write_hame_pixel (x, y, Red, Green, Blue));
  1015.    else if (DisplayFormat == 'F')
  1016.     return (write_firecracker_pixel((UWORD) x, (UWORD) y,
  1017.         (UBYTE) Red, (UBYTE) Green, (UBYTE) Blue));
  1018.    else
  1019.     return (write_ham_pixel ((UWORD) x, (UWORD) y,
  1020.         (UBYTE) Red, (UBYTE) Green, (UBYTE) Blue));
  1021.    }
  1022.  
  1023. int amiga_close_all ()
  1024.    {
  1025.    close_all();
  1026.    return (1);
  1027.    }
  1028.